﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    //饿汉模式
    public class SingletonDemo3
    {
        private static SingletonDemo3 instance = new SingletonDemo3();
        private SingletonDemo3() { }
        public static SingletonDemo3 getInstance()
        {
            return instance;
        }
    }
    /// <summary>
    /// 单例模式的实现 饿汉
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        // 定义私有构造函数，使外界不能创建该类实例
        private Singleton()
        {
            //防止反射来调用
            if (uniqueInstance != null)
            {
                throw new Exception("已经存在实例，无法创建新实例！");

            }
        }



        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }
    //public class B
    //{

    //    static object ob;
    //    //字段
    //    private static B b;
    //    private B()
    //    {
    //        //防止反射来调用
    //        if (b != null)
    //        {
    //            throw new Exception("已经存在实例，无法创建新实例！");

    //        }
    //    }
    //    public static B test()
    //    {

    //        if (b == null)
    //        {
    //            lock (ob)
    //            {
    //                if (b == null)
    //                {
    //                    b = new B();
    //                }
    //            }
    //        }

    //        return b;
    //    }
    //    //属性
    //    private string ss { get; set; }

    //}
}
